#![allow(dead_code)]

use libp2p::core::Multiaddr;
use libp2p::gossipsub::ValidationMode;
use tokio::time::Duration;

pub struct Libp2pConfig {
    pub transport: TransportConfig,
    pub discovery: DiscoveryConfig,
    pub protocols: ProtocolConfig,
}

pub struct TransportConfig {
    pub tcp_port: u16,
    pub enable_quic: bool,
    pub websocket: bool,
}

pub struct DiscoveryConfig {
    pub mdns_enabled: bool,
    pub kad_bootstrap: Vec<Multiaddr>,
}

#[derive(Clone)]
pub struct ProtocolConfig {
    /// Kademlia 配置
    pub kad: KadConfig,

    /// mDNS 配置
    pub mdns: MdnsConfig,

    /// Gossipsub 配置
    pub gossipsub: GossipsubConfig,

    /// 请求响应协议配置
    pub req_res: ReqResConfig,
}

#[derive(Clone)]
pub struct KadConfig {
    pub bootstrap_interval: Duration,
    pub query_timeout: Duration,
    pub replication_factor: usize,
}

// type MessageIdFn = fn(&libp2p::gossipsub::Message) -> libp2p::gossipsub::MessageId;

#[derive(Clone)]
pub struct GossipsubConfig {
    pub topics: Vec<String>,
    // pub message_id_fn: MessageIdFn,
    pub validation_mode: ValidationMode,
}

#[derive(Clone)]
pub struct MdnsConfig {
    pub ttl: Duration,
    /// Interval at which to poll the network for new peers. This isn't
    /// necessary during normal operation but avoids the case that an
    /// initial packet was lost and not discovering any peers until a new
    /// peer joins the network. Receiving an mdns packet resets the timer
    /// preventing unnecessary traffic.
    pub query_interval: Duration,
    /// Use IPv6 instead of IPv4.
    pub enable_ipv6: bool,
}

#[derive(Clone)]
pub struct ReqResConfig {
    max_request_size: usize,
    request_timeout: Duration,
    max_concurrent_streams: usize,
}

impl Default for ProtocolConfig {
    fn default() -> Self {
        Self {
            kad: KadConfig {
                bootstrap_interval: Duration::from_secs(300),
                query_timeout: Duration::from_secs(10),
                replication_factor: 20,
            },
            mdns: MdnsConfig {
                ttl: Duration::from_secs(6 * 60),
                query_interval: Duration::from_secs(5 * 60),
                enable_ipv6: false,
            },
            gossipsub: GossipsubConfig {
                topics: vec!["blocks".into(), "transactions".into()],
                // message_id_fn: DEFAULT_MESSAGE_ID_FN,
                validation_mode: ValidationMode::Strict,
            },
            req_res: ReqResConfig {
                max_request_size: 1024 * 1024, // 1MB
                request_timeout: Duration::from_secs(30),
                max_concurrent_streams: 100,
            },
        }
    }
}
